// -----------------------------------------------------------------------
//  <copyright file="MailKitE_options.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2022 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2022-12-25 18:09</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Net;

using Shares.Infrastructure.Properties;

using MailKit.Net.Smtp;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

using MimeKit;
using MimeKit.Text;

using OSharp.Extensions;


namespace Shares.Infrastructure.Net;

public class MailKitEmailSender : IEmailSender
{
    private readonly ILogger<MailKitEmailSender> _logger;
    private readonly SmtpOptions _options;

    /// <summary>
    /// 初始化一个<see cref="MailKitEmailSender"/>类型的新实例
    /// </summary>
    public MailKitEmailSender(IServiceProvider provider)
    {
        _logger = provider.GetLogger<MailKitEmailSender>();
        _options = provider.GetService<IOptions<SmtpOptions>>()?.Value
            ?? throw new InvalidOperationException(ResSharesInfrastructure.Ex_Init_SmtpOptions);
    }

    public async Task SendAsync(string email, string subject, string htmlMessage)
    {
        if (_options.Host.IsNullOrEmpty() || _options.UserName.IsNullOrEmpty())
        {
            throw new InvalidOperationException(ResSharesInfrastructure.Ex_Init_SmtpOptions);
        }
        string host = _options.Host!,
            displayName = _options.DisplayName!,
            userName = _options.UserName!,
            password = _options.Password!;
        var enableSsl = _options.EnableSsl;
        var port = _options.Port;
        if (port == 0)
        {
            port = enableSsl ? 465 : 25;
        }

        var sender = new MailboxAddress(displayName, userName);
        var mime = new MimeMessage()
        {
            Sender = sender,
            Subject = subject,
            Body = new TextPart(TextFormat.Html) { Text = htmlMessage }
        };
        mime.From.Add(sender);
        mime.To.Add(new MailboxAddress("", email));
        using var smtp = new SmtpClient();
        smtp.MessageSent += (s, e) =>
        {
            _logger.LogInformation(ResSharesInfrastructure.Log_SendEmail, subject, email, e.Response);
        };
        smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
        await smtp.ConnectAsync(host, port, enableSsl);
        await smtp.AuthenticateAsync(userName, password);
        await smtp.SendAsync(mime);
        await smtp.DisconnectAsync(true);
    }
}
